# The Flutter tooling requires that developers have a version of Visual Studio
# installed that includes CMake 3.14 or later. You should not increase this
# version, as doing so will cause the plugin to fail to compile for some
# customers of the plugin.
cmake_minimum_required(VERSION 3.14)

# Project-level configuration.
set(PROJECT_NAME "webcrypto")
project(${PROJECT_NAME} LANGUAGES C CXX)

# --- BoringSSL Config ---

# BoringSSL needs NASM in windows to build assembly files
enable_language(ASM_NASM)

# Set the BoringSSL root directory
set(BORINGSSL_ROOT ../third_party/boringssl/)

# Import BoringSSL sources as generated by tool/update-boringssl.py
include(
  ../third_party/boringssl/sources.cmake
)

# Tradeoff performance for smaller binary size, see:
# https://boringssl.googlesource.com/boringssl/+/HEAD/BUILDING.md#binary-size
add_definitions(-DOPENSSL_SMALL)

# Logic from CMakeLists.txt in BoringSSL
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
  set(ARCH "x86_64")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "amd64")
  set(ARCH "x86_64")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AMD64")
  if(CMAKE_SIZEOF_VOID_P EQUAL 8)
    set(ARCH "x86_64")
  else()
    set(ARCH "x86")
  endif()
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86")
  set(ARCH "x86")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i386")
  set(ARCH "x86")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "i686")
  set(ARCH "x86")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
  set(ARCH "aarch64")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm64")
  set(ARCH "aarch64")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "arm64e")
  set(ARCH "aarch64")
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "^arm*")
  set(ARCH "arm")
elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "ppc64le")
  set(ARCH "ppc64le")
else()
  set(ARCH "generic")
endif()

set(PLATFORM "win")

# If there is no assembly files disable ASM and set empty sources list
if(NOT DEFINED crypto_sources_${PLATFORM}_${ARCH})
  add_definitions(-DOPENSSL_NO_ASM)
  set(crypto_sources_${PLATFORM}_${ARCH})
endif()

# ---- Windows/MSVC option from CMakeLists.txt in BoringSSL -----

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS true)

set(MSVC_DISABLED_WARNINGS_LIST
    "C4100" # 'exarg' : unreferenced formal parameter
    "C4127" # conditional expression is constant
    "C4244" # 'function' : conversion from 'int' to 'uint8_t',
            # possible loss of data
    "C4267" # conversion from 'size_t' to 'int', possible loss of data
    "C4706" # assignment within conditional expression
    )
string(REPLACE "C" " -wd" MSVC_DISABLED_WARNINGS_STR
                          ${MSVC_DISABLED_WARNINGS_LIST})
set(CMAKE_C_FLAGS   "-utf-8 -W4 -WX ${MSVC_DISABLED_WARNINGS_STR}")
set(CMAKE_CXX_FLAGS "-utf-8 -W4 -WX ${MSVC_DISABLED_WARNINGS_STR}")

# On Windows, prefer cl over gcc if both are available. By default most of
# the CMake generators prefer gcc, even on Windows.
set(CMAKE_GENERATOR_CC cl)

add_definitions(-D_HAS_EXCEPTIONS=0)
add_definitions(-DWIN32_LEAN_AND_MEAN)
add_definitions(-DNOMINMAX)
# Allow use of fopen.
add_definitions(-D_CRT_SECURE_NO_WARNINGS)

add_library(
  webcrypto

  # Build a shared library
  SHARED

  # Source files
  ../src/webcrypto.c
  ../src/symbols.generated.c
  ${crypto_sources}
  ${crypto_sources_${PLATFORM}_${ARCH}}
)

target_include_directories(
  webcrypto

  PRIVATE

  ../third_party/boringssl/src/include/
)

set_target_properties(
  webcrypto

  PROPERTIES

  C_VISIBILITY_PRESET hidden
  VISIBILITY_INLINES_HIDDEN 1
  LINKER_LANGUAGE C
)

# --- Flutter Config ---

# This value is used when generating builds using this plugin, so it must
# not be changed
set(PLUGIN_NAME "webcrypto_plugin")

# Any new source files that you add to the plugin should be added here.
list(APPEND PLUGIN_SOURCES
  "webcrypto_plugin.cpp"
  "include/webcrypto/webcrypto_plugin.h"
)

# Define the plugin library target. Its name must not be changed (see comment
# on PLUGIN_NAME above).
add_library(${PLUGIN_NAME} SHARED
  ${PLUGIN_SOURCES}
)

# Apply a standard set of build settings that are configured in the
# application-level CMakeLists.txt. This can be removed for plugins that want
# full control over build settings.
apply_standard_settings(${PLUGIN_NAME})

# Symbols are hidden by default to reduce the chance of accidental conflicts
# between plugins. This should not be removed; any symbols that should be
# exported should be explicitly exported with the FLUTTER_PLUGIN_EXPORT macro.
set_target_properties(${PLUGIN_NAME} PROPERTIES
  CXX_VISIBILITY_PRESET hidden)
target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL)

# Source include directories and library dependencies. Add any plugin-specific
# dependencies here.
target_include_directories(${PLUGIN_NAME} INTERFACE
  "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin)

# List of absolute paths to libraries that should be bundled with the plugin.
# This list could contain prebuilt libraries, or libraries created by an
# external build triggered from this build file.
set(webcrypto_bundled_libraries
  "$<TARGET_FILE:webcrypto>"
  PARENT_SCOPE
)
